import java.util.Vector;
import java.io.Serializable;
import java.lang.Exception;
import java.lang.reflect.Array;

/**
 *
 * @author tim
 */
public class Assembled implements Serializable
{
	Vector label;
	Vector position;
	Vector code;
	int startPc;
	int[] memory;
	int memoryPointer;
	String buildErrors;
	boolean exitFlagThrown;
	
	public Assembled()
	{
		label = new Vector();
		position = new Vector();
		code = new Vector();
		startPc = 0;
		memory = new int[100];
		memoryPointer = 0;
		buildErrors = "";
		exitFlagThrown = false;
	}
	
	public int getStartPC()
	{
		return startPc;
	}
	
	public int[] getLine(int lineNumber)
	{
	     if(exitFlagThrown)
	     {
		  int[] a = new int[1];
		  a[0] = -1;
		  return a;
	     }
		try
		{
			return (int[])code.get(lineNumber);
		}
		catch(Exception e)
		{
			int[] a = new int[1];
			a[0] = -1;
			return a;
		}
	}
	
	public void addLine(int[] line)
	{
		code.add(line);
	}
	
	public void addLabel(String labelName, int address)
	{
		label.add(labelName);
		position.add(address);
		
		if(labelName.equals("main") || labelName.equals("Main"))
			startPc = address;
	}
	
	public void addMemory(String labelName, int[] value)
	{
		int size;
		label.add(labelName);
		position.add(memoryPointer);
		size = Array.getLength(value);
		if((memoryPointer + size + 1) >= Array.getLength(memory))
		{
			int memSize = Array.getLength(memory);
			int[] temp = new int[2*memSize];
			for(int i = 0; i < memSize; ++i)
				temp[i] = memory[i];
                        
                        memory = temp;
		}
		
		for(int i = 0; i < size; ++i)
			memory[memoryPointer + i] = value[i];
                
                memory[memoryPointer + size] = -1;
		
		memoryPointer = memoryPointer + size + 1;
	}
	
	public int[] getInitialMemory()
	{
		return memory;
	}
	public int getLabelAddress(String labelName)
	{
		int i = 0;
		if(!label.contains(labelName))
			return -1;
		while(i < label.size())
		{
			if(label.get(i).equals(labelName))
			{
				try
				{
					return (int)(Integer)position.get(i);
				}
				catch(Exception e)
				{
					return -1;
				}
			}
			++i;
		}
		return -1;
	}
	public void add32bit(String labelName, int value)
	{
	     label.add(labelName);
	     position.add(memoryPointer);
	     if(memoryPointer + 1 >= Array.getLength(memory))
	     {
		    int memSize = Array.getLength(memory);
		    int[] temp = new int[2*memSize];
		    for(int i = 0; i < memSize; ++i)
			 temp[i] = memory[i];

		    memory = temp;
	     }
	     memory[memoryPointer] = value;
	     ++memoryPointer;
	}
	public void add64bit(String labelName, int[] value)
	{
	     label.add(labelName);
	     position.add(memoryPointer);
	     if(memoryPointer + 2 >= Array.getLength(memory))
	     {
		  int memSize = Array.getLength(memory);
		  int[] temp = new int[2*memSize];
		  for(int i = 0; i < memSize; ++i)
			 temp[i] = memory[i];

		  memory = temp;
	     }
	     memory[memoryPointer] = value[0];
	     memory[memoryPointer + 1] = value[1];
	     memoryPointer = memoryPointer + 2;
	}
	public void reset()
	{
	     exitFlagThrown = false;
	}
	public void throwExit()
	{
	     exitFlagThrown = true;
	}
	public void addError(String errorMessage)
	{
	     buildErrors = errorMessage + "\n";
	}
	public String getBuildErrors()
	{
	     return buildErrors;
	}
}
